package com.mobi.Survey.map;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.http.ParseException;

import android.content.Context;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.mobi.Survey.lib.model.Address;
import com.mobi.Survey.lib.model.LatLong;
import com.mobi.Survey.lib.model.SurveysJsonParser;
import com.mobi.Survey.lib.utils.Helper;

public class MapSurveysJsonParser extends SurveysJsonParser {
	private Context context;
	private Map<Address, LatLong> coordinates = new HashMap<Address, LatLong>();

	public MapSurveysJsonParser(Context ctx) {
		this.context = ctx;
	}

	protected void fillCoordinates(Address address) {
		try {
			LatLong latLong = coordinates.get(address);
			if (null != latLong) {
				address.setCoordinates(latLong);
			} else {
				MapHelper.fillLangLat(context, address);
				coordinates.put(address, address.getCoordinates());

			}

		} catch (IOException e) {

			e.printStackTrace();
		}

	}

	private final List<MapMarker> parseJsonForMapWithJacksonStream(
			JsonParser jParser,
			Map<MapMarker, Integer> markersWithDuplicateCount)
			throws JsonParseException, IOException {

		List<MapMarker> marks = new ArrayList<MapMarker>();
		Set<MapMarker> markerSet = new HashSet<MapMarker>();
		String tokenValue = null;
		int totalMarkers = 0;
		while (jParser.nextToken() != JsonToken.END_OBJECT) {

			String fieldname = jParser.getCurrentName();

			if ("statusValue".equals(fieldname)) {
				jParser.nextToken();
				tokenValue = jParser.getText();

				if (null != tokenValue && tokenValue.trim().length() > 0) {
					if (!tokenValue.trim().equals("1")) {
						throw new RuntimeException(
								"Error : statusValue is not equal to 1");
					}
				} else {
					break;
				}
			} else if("TotalCount".equals(fieldname)){
				jParser.nextToken();
				tokenValue = jParser.getText();
				totalMarkers = Helper.toInt(tokenValue);
				 
			}
			
			else if ("surveys".equals(fieldname)) {
				tokenValue = null;
				MapMarker marker = null;

				while (jParser.nextToken() != JsonToken.END_ARRAY) {
					fieldname = jParser.getCurrentName();
					if (jParser.getCurrentToken() == JsonToken.START_OBJECT) {
						marker = new MapMarker();
						marker.setTotalPoints(totalMarkers);

					} else if ("FormDescription".equals(fieldname)) {
						jParser.nextToken();
						tokenValue = jParser.getText();
						if (null != tokenValue
								&& tokenValue.trim().length() > 0) {
							marker.setDescription(tokenValue);
						}

					}else if("icon_url".equals(fieldname)){
						jParser.nextToken();
						tokenValue = jParser.getText();
						if (null != tokenValue
								&& tokenValue.trim().length() > 0) {
							marker.setIconUrl(tokenValue.trim());
						}
					}
					
					else if ("Latitude".equals(fieldname)) {
						jParser.nextToken();
						tokenValue = jParser.getText();
						if (null != tokenValue
								&& tokenValue.trim().length() > 0) {
							marker.setLatitude(tokenValue.trim());
						}

					} else if ("Longitude".equals(fieldname)) {
						jParser.nextToken();
						tokenValue = jParser.getText();
						if (null != tokenValue
								&& tokenValue.trim().length() > 0) {
							marker.setLongitude(tokenValue.trim());
						}

					} else if ("formId".equals(fieldname)) {
						jParser.nextToken();
						tokenValue = jParser.getText();

						long id = Helper.toLong(tokenValue);
						if (id > 0) {
							marker.setSurveyId(id);
						}

					} else if ("info".equals(fieldname)) {
						jParser.nextToken();
						tokenValue = jParser.getText();

					} else if ("userId".equals(fieldname)) {
						jParser.nextToken();
						tokenValue = jParser.getText();
						if (null != tokenValue
								&& tokenValue.trim().length() > 0) {
							marker.setUserId(tokenValue.trim());
						}

					}
					if (jParser.getCurrentToken() == JsonToken.END_OBJECT) {
						if (null != marker && marker.getSurveyId() > 0
								&& marker.getLongitude().length() > 0
								&& marker.getLatitude().length() > 0 /*&& !marker.getLatitude().equals("0.000000")&& !marker.getLongitude().equals("0.000000")*/) {
							marks.add(marker);

							if (!markerSet.add(marker)) {
								Integer count = markersWithDuplicateCount
										.get(marker);
								if (null == count) {
									// setting initial count to 2
									markersWithDuplicateCount.put(marker, 2);
								} else {
									count++; // found duplicate, increment by 1
									markersWithDuplicateCount
											.put(marker, count);
								}
							}
						}
					}
				}
			}
		}
		return marks;
	}

	@SuppressWarnings("deprecation")
	public List<MapMarker> parseForMap(InputStream json,
			Map<MapMarker, Integer> markerWithDuplicateCount)
			throws IOException {

		JsonParser jParser = null;
		if (jsonFactory == null)
			jsonFactory = new JsonFactory();
		if (json != null) {
			jParser = jsonFactory.createJsonParser(json);
			return parseJsonForMapWithJacksonStream(jParser,
					markerWithDuplicateCount);
		} else {
			throw new ParseException();
		}

	}

	@SuppressWarnings("deprecation")
	public List<MapMarker> parseForMap(String json,
			Map<MapMarker, Integer> markerWithDuplicateCount)
			throws IOException {

		JsonParser jParser = null;
		if (jsonFactory == null)
			jsonFactory = new JsonFactory();
		if (json != null) {
			jParser = jsonFactory.createJsonParser(json);
			return parseJsonForMapWithJacksonStream(jParser,
					markerWithDuplicateCount);
		} else {
			throw new ParseException();
		}

	}


}
